/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../macro/head.h"
#include "aio_helper.h"
#include "aio_impl.h"
#include "aio_tcp.h"
#include "aio_udp.h"
#include "mgr.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos_aio
{
    aio_helper::aio_helper( aio_impl * pAioImpl ) : m_pAioImpl( pAioImpl )
    {
    }

    aio_helper::~aio_helper()
    {
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // 
    // 
    int aio_helper::proc( int nResult, DWORD dwBytes, aio_key * lpKey, aio_data * lpData )
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = on_tcp( nResult, dwBytes, lpKey, lpData );
        }

        if( 0 == ret )
        {
            ret = on_udp( nResult, dwBytes, lpKey, lpData );
        }

        if( lpData )
        {
            lpData->m_lpMsgData = 0;
            lpData->release();
            lpData = 0;
        }

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // 
    // 
    int aio_helper::on_tcp( int nResult, DWORD dwBytes, aio_key * lpKey, aio_data * lpData )
    {
        int ret = 1;

        aio_tcp tcp( m_pAioImpl );

        switch( lpData->m_nType )
        {
            case i_aio::AIO_TCP_INIT:
            {
                tcp.tcp_init( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_CONNECT_RET:
            {
                tcp.tcp_connect_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_CONNECT:
            {
                tcp.tcp_connect( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_ACCPET_RET:
            {
                tcp.tcp_accept_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_ACCPET:
            {
                tcp.tcp_accept( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_RECV_RET:
            {
                tcp.tcp_recv_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_RECV:
            {
                tcp.tcp_recv( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_SEND_RET:
            {
                tcp.tcp_send_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_SEND:
            {
                tcp.tcp_send( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_SHUTDOWN_RET:
            {
                tcp.shut_down_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_SHUTDOWN:
            {
                tcp.shut_down( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_CLOSE_RET:
            {
                tcp.close_net_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_TCP_CLOSE:
            {
                tcp.close_net( nResult, dwBytes, lpKey, lpData );
            }
            break;
            default:
            {
                ret = 0;
            }
            break;
        }

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // 
    // 
    int aio_helper::on_udp( int nResult, DWORD dwBytes, aio_key * lpKey, aio_data * lpData )
    {
        int ret = 1;

        aio_udp udp( m_pAioImpl );

        switch( lpData->m_nType )
        {
            case i_aio::AIO_UDP_INIT:
            {
                udp.udp_init( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_RECV_RET:
            {
                udp.udp_recv_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_RECV:
            {
                udp.udp_recv( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_SEND_RET:
            {
                udp.udp_send_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_SEND:
            {
                udp.udp_send( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_SHUTDOWN_RET:
            {
                udp.shut_down_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_SHUTDOWN:
            {
                udp.shut_down( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_CLOSE_RET:
            {
                udp.close_net_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
            case i_aio::AIO_UDP_CLOSE:
            {
                udp.close_net( nResult, dwBytes, lpKey, lpData );
            }
            break;
            default:
            {
                ret = 0;
            }
            break;
        }

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int aio_helper::post_msg( xos_box::i_msg *& pMsg )
    {
        int nRet = 0;

        aio_data * pData = aio_data::get_item_from_pool();
        pData->init();
        pData->m_nType = pMsg->get_msg( 0, 0 );
        pData->m_lpMsgData = pMsg;
        PostQueuedCompletionStatus( m_pAioImpl->m_hIocp, 0, 0, (WSAOVERLAPPED *)&pData->m_ov_ex );
        pData = 0;
        pMsg = 0;

        return nRet;
    }

} // xos_aio
